home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Apple II Magazines (PO)
/
Nibble Volume 09, No. 05 (1988-05)(MicroSPARC)(Side A).zip
/
Nibble Volume 09, No. 05 (1988-05)(MicroSPARC)(Side A).po
/
REPRO.DIR.B.S
< prev
next >
Wrap
Text File
|
1996-12-24
|
18KB
|
657 lines
SBTL "ProDOS REPRO COMMAND"
**************************
* REPRO.DIR *
* ProDOS REPRO Command *
* by Leh-Wen Yau *
* Copyright (C) 1988 *
* By MicroSPARC, Inc. *
* Concord, MA 01742 *
* EDASM.SYSTEM Assembler *
**************************
*
*
COPYALL EQU $8000
COPY EQU $8156 @ "Get FN1 info" heading of COPY.ALL
* COPY.ALL addresses
* Make sure these addresses are adjusted with future
* enhancements of Sandy Mossberg's COPY.ALL Program
*
* General Equates
*
A1L EQU $3C MOVE start
A2L EQU $3E MOVE end
A4L EQU $42 MOVE destination
STREND EQU $6D Bottom of free space
FRETOP EQU $6F Bottom of strings
MEMSIZ EQU $73 HIMEM
INBUF EQU $200 Input buffer
FN1INFO EQU $2EE File info buffer used in COPY
KEY EQU $C000 Keyboard input
MOVE EQU $FE2C Monitor move
*
* BI Global Page Equates
*
EXTRNCMD EQU $BE06 External command
XTRNADDR EQU $BE50 External command execution
XLEN EQU $BE52 Command length minus one
XCNUM EQU $BE53 Command number (ext cmd=0)
PBITS EQU $BE54 Permitted parameter bits
FBITS EQU $BE56 Found parameter bits
VPATH1 EQU $BE6C Pathname 1 buffer pointer
VPATH2 EQU $BE6E Pathname 2 buffer pointer
GOSYSTEM EQU $BE70 Execute MLI call
CRACESS EQU $BEA3 CREATE access code
CRFKIND EQU $BEA7 CREATE storage type code
SSGINFO EQU $BEB4 FILE.INFO parameter count
FIFILID EQU $BEB8 FILE.INFO file type code
FIMDATE EQU $BEBE FILE.INFO modification date
OSYSBUF EQU $BECE OPEN buffer pointer
OREFNUM EQU $BED0 OPEN reference number
RWREFNUM EQU $BED6 READ/WRITE reference number
RWDATA EQU $BED7 READ/WRITE buffer pointer
RWCOUNT EQU $BED9 READ/WRITE number bytes to R/W
CFREFNUM EQU $BEDE CLOSE reference number
GETBUFR EQU $BEF5 Allocate buffer space
FRBUFRS EQU $BEF8 Free all buffer space
*
* ProDOS System Global Page
*
DEVADR31 EQU $BF16 Slot 3 drive 1 device driver address
DEVADR32 EQU $BF26 Slot 3 drive 2 device driver address
MACHID EQU $BF98 Machine ID byte
*
* MLI calls
*
CREATE EQU $C0 CREATE
GFILINFO EQU $C4 GET.FILE.INFO
OPEN EQU $C8 OPEN
READ EQU $CA READ
CLOSE EQU $CC CLOSE
*
* Zero Page Command Storage Equates
*
OFFSET EQU $06 Offset for relocation
DIR1REF EQU $06 DIR1 reference number
FILECNT EQU $07 Directory block file entry counter
BUFFPTR EQU $08 Directory block buffer pointer
SUBCMD EQU $1E REPRO sub-command save
FILEPTR EQU $CE File entry pointer
PTR1 EQU $EC Pointer
PTR2 EQU $EE Pointer
PTR3 EQU $F9 Pointer
PTR4 EQU $FB Pointer
*
LST GEN
MSB ON
ORG $7C00
*
*
* INSTALLATION
*
* Save external command address before installing COPY.ALL
*
LDY EXTRNCMD+1
LDA EXTRNCMD+2
STY OLDCMDADR
STA OLDCMDADR+1
*
* Install COPY.ALL
*
JSR COPYALL Install COPY command
*
* Allocate buffer for REPRO command code
*
LDA #<CMDEND-CMDPARSE Get desired # of pages
JSR GETBUFR
BCS NOBFERR Buffer allocation error
STA A4L+1 Destination MSB
PHA Save starting address MSB
*
* Calculate offset between load and final address
*
SEC
SBC #<CMDPARSE
STA OFFSET
*
* Relocate absolute internal references
*
LDY #0
LDX #RELOCLEN
RELOC LDA RELOCTBL-1,X
STA PTR1+1
DEX
LDA RELOCTBL-1,X
STA PTR1
CLC
LDA (PTR1),Y
ADC OFFSET
STA (PTR1),Y
DEX
BNE RELOC
*
* Set link to next external command (or RTS)
*
LDY EXTRNCMD+1
LDA EXTRNCMD+2
STY CMDLINK+1
STA CMDLINK+2
STA JSRCOPY+2 Also take care of JSR COPY address
*
* Move command code to final location
*
LDY #>CMDPARSE
LDA #<CMDPARSE
STY A1L Start LSB
STA A1L+1 Start MSB
LDY #>CODEEND
LDA #<CODEEND
STY A2L End LSB
STA A2L+1 End MSB
LDY #0
STY A4L Destination LSB
JSR MOVE Y=0 for monitor move
*
* Point EXTRNCMD at command code and exit
*
LDY #0
PLA Restore starting address MSB
STY EXTRNCMD+1
STA EXTRNCMD+2
RTS
*
* Generate NO BUFFER AVAILABLE error
*
NOBFERR LDA #$C
RTS
*
* Relocate table
*
RELOCTBL DW reloc1+2
DW reloc2+1
DW reloc3+2
DW reloc4+2
DW reloc5+2
DW reloc6+1
DW reloc7+2
RELOCLEN EQU *-RELOCTBL
*
here EQU >*
DS $100-here,$00 Force page boundary and fill with zero
*
* COMMAND PARSING
*
* Check for valid command
*
CMDPARSE LDX #0
LDY #0
CMDLOOP LDA INBUF,X Get INBUF char
INX
CMP #$A0
BEQ CMDLOOP Ignore space char
AND #$DF Ensure upper case
reloc1 EOR CMDTXT,Y
BNE INVALID REPRO command not found
INY
CPY #CMDLEN
BCC CMDLOOP Get another char
*
* Valid command found
*
* -> Determine if sub-command specified
*
LDA #0 Initialize sub-command
STA SUBCMD
LDA INBUF,X
CMP #'# Looking for a pound sign
BNE SETXLEN Not found - no sub-command
INX
INY
LDA INBUF,X Get sub-command code
AND #$DF Ensure upper case
CMP #'S SCRATCHRAM sub-command?
BEQ CMDSYN1 Good sub-command
CMP #'D DEINSTALL sub-command?
BEQ CMDSYN1 Good sub-command
CMP #'B SCRATCHRAM and DEINSTALL sub-command?
BEQ CMDSYN1 Good sub-command
SEC Signal syntax error
RTS Return to BI
CMDSYN1 STA SUBCMD Save sub-command
INX
INY
*
* -> Store length of command string minus one
*
SETXLEN DEY
STY XLEN
*
* -> Flag external command
*
LDA #0
STA XCNUM
*
* -> Set permitted parameter bits (PBITS/PBITS+1)
*
STA PBITS+1 Allow no letter parameters
LDA #3
STA PBITS Allow DIR1 and DIR2
*
* -> Point BI at command execution code
*
LDY #>CMDEXEC
reloc2 LDA #<CMDEXEC
STY XTRNADDR
STA XTRNADDR+1
*
* Return control to BI
*
CLC Signal no error
RTS
*
* Valid command string not found
*
INVALID SEC
CMDLINK JMP $0000 Link addr to external command
*
OLDCMDADR DW 0 External command addr before install COPY
*
* Text of REPRO command
*
CMDTXT ASC "REPRO"
CMDLEN EQU *-CMDTXT
*
* COMMAND EXECUTION
*
* Check that both filenames given
*
CMDEXEC LDA FBITS
LSR
BCC SYNERR DIR1 not found
LSR
BCC SYNERR DIR2 not found
*
* Check for sub-command to scratch /RAM disk
*
LDA SUBCMD Check sub-command
CMP #'S Is SCRATCHRAM specified?
BEQ CKSUBCMD1 Yes - proceed
CMP #'B Both SCRATCHRAM and DEINSTALL specified?
BNE CKBUFR No - proceed
LDA #'D Set DEINSTALL sub-command for later
STA SUBCMD
reloc3 EQU *
CKSUBCMD1 JSR INITRAM Go initializing /RAM disk
*
* Check for at least 13 full pages of free space
*
CKBUFR LDA FRETOP+1
SBC STREND+1
CMP #14
BCC NOBUFERR Not enough pages
LDY #0 Set directory buffer pointer
STY BUFFPTR in Zero Page
LDA STREND+1 Set file buffer above
CLC buffer used by COPY command
ADC #8 6 pages reserved by COPY
STA BUFFPTR+1 1 page to store diretory pathnames
*
* Get DIR1 info
*
LDA #$A Set GET.FILE.INFO
STA SSGINFO parameter count
LDA #GFILINFO
JSR GOSYSTEM GET.FILE.INFO call
BCS RTS1 Error
*
* Reject non-directory file
*
LDA FIFILID
CMP #$F
BNE FTMISERR Not a directory file
*
* Set buffer pointer and save pathnames
*
LDY BUFFPTR+1 Set directory pathname
DEY save area pointer
STY PTR2+1
LDA VPATH1 Get source directory pathname pointer
LDY VPATH1+1
STA PTR1 Set it in Zero Page
STY PTR1+1
LDA #$80 Get source directory pathname buffer
SAVEPATH STA PTR2
LDY #0
LDA (PTR1),Y Get directory pathname length
TAY
SAVE1 LDA (PTR1),Y Save directory pathname
STA (PTR2),Y
DEY
BPL SAVE1
LDA PTR2
CMP #$C0 Are we processing target directory?
BGE OPENDIR1 Yes - done!
LDA VPATH2 Get target directory pathname pointer
LDY VPATH2+1
STA PTR1
STY PTR1+1
LDA #$C0 Get target directory pathname savearea
BNE SAVEPATH (always) save it
*
* Generate SYNTAX ERROR
*
SYNERR LDA #$10
DB $2C Skip next 2-byte instruction
*
* Generate FILE TYPE MISMATCH error
*
FTMISERR LDA #$D
DB $2C Skip next 2 byte instruction
*
* Generate NO BUFFERS AVAILABLE error
*
NOBUFERR LDA #$C
SEC
RTS1 RTS
*
* Open DIR1 and save reference number
*
OPENDIR1 LDY BUFFPTR+1 Get directory buffer pointer
INY Reserve 2 pages for R/W buffer
INY
STY OSYSBUF+1 Set file buffer
LDA #OPEN
JSR GOSYSTEM OPEN call
BCS RTS1 Error
LDA OREFNUM
STA DIR1REF Save DIR1 reference number
*
* Copy DIR2 to filename buffer pointed to in OPEN parmlist
*
LDA VPATH1
STA PTR1 DIR1 pointer LSB
LDA VPATH1+1
STA PTR1+1 DIR1 pointer MSB
LDA VPATH2
STA PTR2 DIR2 pointer LSB
LDA VPATH2+1
STA PTR2+1 DIR2 pointer MSB
LDY #0
LDA (PTR2),Y Get length byte of DIR2
TAY
p2 LDA (PTR2),Y Copy DIR2 to
STA (PTR1),Y DIR1 buffer
DEY
BPL p2
*
* Get DIR2 info
*
LDA #GFILINFO
JSR GOSYSTEM GET.FILE.INFO call
BCS CKFNFERR Error, hopefully just a NOT FOUND
LDA FIFILID
CMP #$F
BNE FTMISERR Not a directory file
BEQ CKESC Target directory already exist
*
* Check fatal GET.FILE.INFO error
*
CKFNFERR CMP #6 Report all errors except
BCC ERREXIT volume directory, pathname
CMP #7 or filename not found
BNE ERREXIT (BI error code 6,7)
*
* Create DIR2
*
LDA #$C3 Ensure free access
STA CRACESS Set access code
LDA #$F Set file type code
STA CRACESS+1 to directory
LDA #$D Set storage type to
STA CRFKIND linked directory file
LDA #0 Zero out
STA CRACESS+2 auxiliary data
STA CRACESS+3
STA CRFKIND+1 date of creation
STA CRFKIND+2
STA CRFKIND+3 time of creation
STA CRFKIND+4
LDA #CREATE
JSR GOSYSTEM CREATE call (for DIR2)
BCS ERREXIT Error
BCC CKESC No error - proceed
*
* Close file(s) and generate error message
*
reloc4 EQU *
ERREXIT JSR CLOSEDIR
SEC
RTS
*
* Read directory block from DIR1 to R/W buffer
*
READDIR LDA DIR1REF Set DIR1 reference number
STA RWREFNUM R/W parmlists
LDY #0
LDA BUFFPTR+1
STY RWDATA Set R/W buffer
STA RWDATA+1
LDA #2 Set # of bytes to be read
STA RWCOUNT+1 equal to 1 block ($200)
STY RWCOUNT
LDA #READ
JSR GOSYSTEM READ call
BCC CHECKDIR No error, examine directory block
CMP #5
BEQ ENDCOPY END OF DATA error so end
BNE ERREXIT Fatal error
*
* Allow abortion of copy with ESC key
*
CKESC LDA KEY Get keystroke
BPL READDIR No key press - read directory
CMP #$9B If ESC pressed
BEQ ENDCOPY then end
BNE READDIR (always) Read directory block
*
* Copy completed so close files, set file into and exit
*
reloc5 EQU *
ENDCOPY JSR CLOSEDIR
LDA SUBCMD Check sub-command
CMP #'D Is DEINSTALL specified?
BNE RTS3 No - exit from REPRO command
LDY #>OLDCMDADR Restore old external command address
reloc6 LDA #<OLDCMDADR back in BI
STY EXTRNCMD+1
STA EXTRNCMD+2
JSR FRBUFRS Free all acquired buffers
RTS3 CLC Tell BI there is no error
RTS EXIT from REPRO command
*
* Process directory block
*
CHECKDIR LDA #4 Initialize file entry pointer
STA FILEPTR
LDA BUFFPTR+1
STA FILEPTR+1
LDY #0 Check previous directory block #
STY FILECNT Initialize file counter
LDA (BUFFPTR),Y Low byte
INY
ORA (BUFFPTR),Y Now check high byte
BNE CHECKFILE Not first block
LDA #$2B First block - skip directory header
STA FILEPTR adjust file entry pointer
INC FILECNT Increment file entry counter
*
* Check file entries
*
CHECKFILE LDY #0
LDA (FILEPTR),Y Check file name length
CMP #$D0 High four bits $D?
BGE CHECK1 Yes - skip subdirectory file
CMP #$10 High four bits zero?
BLT CHECK1 Yes - skip inactive file
reloc7 EQU *
CHECK0 JSR COPYFILE Process file entry
BCC CHECK1 No error - proceed
CMP #$13 DUPLICATE FILE NAME?
BEQ CHECK3 Yes - proceed
BNE ERREXIT No - something bad happened, stop!
CHECK1 LDA FILECNT
CMP #12 Last file entry?
BGE CHECK2 Yes - check for more directory block
INC FILECNT Increment file counter
CLC
LDA FILEPTR Bump up file pointer
ADC #$27
STA FILEPTR
LDA FILEPTR+1
ADC #0
STA FILEPTR+1
BNE CHECKFILE (always) Loop back
CHECK2 LDY #2 Check next directory block number
LDA (BUFFPTR),Y Low byte
INY
ORA (BUFFPTR),Y Now check high byte
BNE CKESC More to go - proceed
BEQ ENDCOPY End of chain - all done!
CHECK3 LDA FIFILID Compare file type
CMP FN1INFO+4
BNE CHECK1 Not the same, don't copy
LDA FIMDATE+1 Compare file modification date
CMP FN1INFO+11 (yyyyyyym)
BLT CHECK4 FN2 is older, replace it
BNE CHECK1 FN2 is newer, don't copy
LDA FIMDATE
CMP FN1INFO+10 (mmmddddd)
BLT CHECK4
BNE CHECK1
LDA FIMDATE+3 Compare file modification time
CMP FN1INFO+13 (hhhhhhhh)
BLT CHECK4
BNE CHECK1
LDA FIMDATE+2
CMP FN1INFO+12 (mmmmmmmm)
BLT CHECK4
BGE CHECK1
CHECK4 LDA #$C1 DESTROY command code
JSR GOSYSTEM Scratch FN2
BCS CHECK1 Error - forget it
BCC CHECK0 Copy again
*
* Construct COPY command and copy file
*
COPYFILE LDY BUFFPTR+1 Set source directory
DEY pathname pointer
STY PTR1+1
STY PTR3+1 (take care of target directory too)
LDA #$80
STA PTR1
LDA VPATH1 Get BI source pathname buffer pointer
LDY VPATH1+1
STA PTR2
STY PTR2+1
LDY #0
LDA (PTR1),Y Get source directory pathname length
TAY
COPY1 LDA (PTR1),Y Move source directory pathname
STA (PTR2),Y to BI source pathname buffer
DEY
BPL COPY1
LDA #$C0 Set target directory pathname pointer
STA PTR3
LDA VPATH2 Get BI target pathname buffer pointer
LDY VPATH2+1
STA PTR4
STY PTR4+1
LDY #0
LDA (PTR3),Y Get target directory pathname length
TAY
COPY2 LDA (PTR3),Y Move target pathname length
STA (PTR4),Y to BI target pathname buffer
DEY
BPL COPY2
LDY #0
LDA (FILEPTR),Y Get file pathname length
AND #$0F Zero out high four bits
TAX Save file pathname length
CLC Adjust BI source pathname length
ADC (PTR1),Y
ADC #1 Add 1 for "/"
STA (PTR2),Y
TXA Restore file pathname length
ADC (PTR3),Y Adjust BI target pathname length
ADC #1 Add 1 for "/"
STA (PTR4),Y
LDA (PTR1),Y Adjust BI source pathname buffer pointer
ADC PTR2
ADC #1 Add 1 for "/"
STA PTR2
LDA PTR2+1
ADC #0
STA PTR2+1
CLC Adjust BI target pathname buffer pointer
LDA (PTR3),Y
ADC PTR4
ADC #1 Add 1 for "/"
STA PTR4
LDA PTR4+1
ADC #0
STA PTR4+1
TXA Restore file pathname length
TAY
COPY3 LDA (FILEPTR),Y Move file pathname
STA (PTR2),Y to BI source and target
STA (PTR4),Y pathname buffer
DEY
BNE COPY3
LDA #$2F "/"
STA (PTR2),Y End of directory pathname marker
STA (PTR4),Y for both source and target files
JSRCOPY JSR COPY Use COPY.ALL Program to copy the file!
RTS
*
* Close DIR1 (internal subroutine)
*
CLOSEDIR PHA Preserve entry A-reg
LDA DIR1REF
STA CFREFNUM Set DIR1 reference number
LDA #CLOSE
JSR GOSYSTEM CLOSE call (DIR1)
PLA Restore entry A-reg
RTS
*
* Initialize /RAM disk
*
INITRAM LDA MACHID Check machine ID byte
AND #$30 Isolate memory bits
CMP #$30 128K?
BNE INITRAM1 No - do nothing
LDA DEVADR32 Check if slot 3,
CMP DEVADR31 drive 1 and drive 2 are the same
BNE INITRAM2 No - /RAM disk installed
LDA DEVADR32+1
CMP DEVADR31+1
BNE INITRAM2
INITRAM1 RTS
INITRAM2 LDA #$B0 Slot 3, drive 2 (dsss0000)
STA $43
LDA #3 Command = FORMAT
STA $42
LDA #0 Use BI general purpose buffer
STA $44
LDA MEMSIZ+1
STA $45
STA $C080 Select language card for driver
JSR INITRAM3 Go format the volume
STA $C081 Select ROM
RTS
INITRAM3 JMP (DEVADR32) Jump to /RAM driver
*
CODEEND EQU *
here2 EQU >*
DS $100-here2,$00 Force page boundary
*
CMDEND EQU *